浅谈 var、let 和 const (二)
前言
在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域。在前一篇文章中,我们讲到了 var、let 和 const 的块级作用域,今天我们主要学习下变量提升和函数提升。
| 声明方式 | 变量提升 | 暂时性死区 | 重复声明 | 初始值 | 作用域 |
|---|---|---|---|---|---|
| var | 允许 | 不存在 | 允许 | 不需要 | 除块级 |
| let | 不允许 | 存在 | 不允许 | 不需要 | 块级 |
| const | 不允许 | 存在 | 不允许 | 需要 | 块级 |
1. 变量提升
定义:变量提升,即将变量声明提升到它所在作用域的最开始的部分。变量声明在编译阶段被处理,而变量赋值则留在原地等待执行。
- var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。
- let 和 const不存在变量提升,所声明的变量一定要在声明后使用,否则报错。
下面给出代码来解释
var 命令 — 存在变量提升
1 | console.log(global); // undefined |
由于js的变量提升,导致代码实际上是按照以下来执行的
1 | var global; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值 |
let — 不存在变量提升
1 | console.log(a); |
const — 不存在变量提升
1 | console.log(a); |
使用 let 和 const 命令声明变量之前,该变量是不可用的。
2. 函数提升
JavaScript中,创建函数主要有两种方式:函数声明式和函数表达式。
1) 函数声明 (Function Declaration);
1 | // 函数声明 |
2) 函数表达式 (Function Expression)。
1 | // 函数表达式 |
编译阶段,JavaScript 引擎能把 函数声明 提升到顶部(即使声明函数的代码在调用它的代码后面)
- 函数声明提升优先于变量声明 (函数的提升优先级最高)。
- 函数声明提升优于函数表达式(函数表达式实际上是变量声明的一种)。
下面给出代码来解释
函数声明
1 | console.log(fn(1)); |
由于函数提升,函数声明被置于执行环境顶部,即使调用函数的代码在声明函数之前也可以正确访问。
函数表达式
var
1 | console.log(fn(1)); |
let(const和let类似)
1 | console.log(fn(1)); |